using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text;
using System.Xml;

using WindowsLive.Writer.Api;


namespace QuotesPlugin
{
    public class Quotes4AllEntry : IQuotesEntry
    {
        #region "Public Properties"
        public string Date;
        public string Time;
        public string QuoteUrl
        {
            get { return this.m_quoteUrl; }
            set { this.m_quoteUrl = value; }
        }

        public string Author
        {
            get { return this.m_author; }
            set { this.m_author = value; }
        }

        public string AuthorFrom 
        {
            get { return this.m_authorFrom; }
            set { this.m_authorFrom = value; }
        }

        public string AuthorTo 
        {
            get { return this.m_authorTo; }
            set { this.m_authorTo = value; }
        }
        
        public string AuthorDescription 
        {
            get { return this.m_authorDescription; }
            set { this.m_authorDescription = value; }
        }
        
        public string AuthorUrl 
        {
            get { return this.m_authorUrl; }
            set { this.m_authorUrl = value; }
        }
        
        public string ImageUrl 
        {
            get { return this.m_imageUrl; }
            set { this.m_imageUrl = value; }
        }
        public string ImageType { get { return this.m_imageType; } }
        public string ImageWidth 
        {
            get { return this.m_imageWidth; }
            set { this.m_imageWidth = value; }
        }
        public string ImageHeight 
        {
            get { return this.m_imageHeight; }
            set { this.m_imageHeight = value; }
        }
        public string ImageSize { get { return this.m_imageSize; } }
        
        public string QuoteText 
        {
            get { return this.m_quoteText; }
            set { this.m_quoteText = value; }
        }

        public override String ToString()
        {
            return QuoteText;
        }

        public Image QuoteImage
        {
            get 
            {
                if (this.ImageUrl != String.Empty)
                {
                    if (m_cachedImage == null)
                    {
                        try
                        {
                            // retrieve the image from web
                            PluginHttpRequest req = new PluginHttpRequest(this.m_imageUrl);
                            Stream stream = req.GetResponse();
                            this.m_cachedImage = Image.FromStream(stream);
                        }
                        catch (System.IO.IOException e)
                        {
                            System.Diagnostics.Debug.Assert(false, e.Message);
                            this.m_cachedImage = null;
                        }
                    }                    
                }
                return m_cachedImage;
            }
        }

        #endregion

        #region "Private Data Members"
        // When and where
        
        string m_quoteUrl;
        
        // Author of the quote
        string m_author;
        string m_authorFrom;
        string m_authorTo;
        string m_authorDescription;
        string m_authorUrl;

        // Image if any
        string m_imageUrl;
        string m_imageType = "";
        string m_imageWidth;
        string m_imageHeight;
        string m_imageSize = "";

        // cache image if retrieved
        Image m_cachedImage;

        // Content
        string m_quoteText;
        #endregion
    }

    class Quotes4AllResponse
    {
        public Quotes4AllResponse(Stream stream)
        {
            xmlStream = stream;
        }
        public IList<Quotes4AllEntry> Parse()
        {
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(this.xmlStream);

                XmlElement root = doc.DocumentElement;
                if (root.HasAttribute("entries"))
                    this.entriesCount = Convert.ToInt32(root.GetAttribute("entries"));
                //TODO: parse date / time format, etc

                foreach (XmlNode quoteNode in root.ChildNodes)
                {
                    XmlElement quoteElement = quoteNode as XmlElement;
                    Quotes4AllEntry entry = new Quotes4AllEntry();
                    if (quoteElement.HasAttribute("date"))
                        entry.Date = quoteElement.GetAttribute("date");
                    if (quoteElement.HasAttribute("time"))
                        entry.Time = quoteElement.GetAttribute("time");
                    if (quoteElement.HasAttribute("url"))
                        entry.QuoteUrl = quoteElement.GetAttribute("url");

                    foreach (XmlNode childNode in quoteElement.ChildNodes)
                    {
                        #region "Parse Author"
                        if (childNode.LocalName == "Author")
                        {
                            entry.Author = getAttribute(childNode, "name");
                            entry.AuthorFrom = getAttribute(childNode, "from");
                            entry.AuthorTo = getAttribute(childNode, "to");
                            entry.AuthorDescription = getAttribute(childNode, "description");
                            entry.AuthorUrl = getAttribute(childNode, "url");
                        }
                        #endregion
                        #region "Parse Image"
                        else if (childNode.LocalName == "Image")
                        {
                            entry.ImageUrl = getAttribute(childNode, "url");
                            entry.ImageHeight = getAttribute(childNode, "height");
                            entry.ImageWidth = getAttribute(childNode, "width");
                            //TODO: file size, width, height
                        }
                        #endregion
                        #region "Parse Quote Text"
                        else if (childNode.LocalName == "Text")
                        {
                            entry.QuoteText = childNode.InnerText.Trim();
                        }
                        #endregion
                    }

                    this.entries.Add(entry);
                }
            }
            catch (XmlException e)
            {
                string msg = e.Message;
            }

            //TODO: Verify the collection
            System.Diagnostics.Debug.Assert(this.entries.Count == this.entriesCount);

            return this.entries;
        }

        private string getAttribute(XmlNode node, String attrName)
        {
            XmlElement elem = node as XmlElement;
            if (elem != null)
            {
                if (elem.HasAttribute(attrName))
                {
                    return elem.Attributes[attrName].Value;
                }
            }

            return "";
        }

        private Stream xmlStream;
        private List<Quotes4AllEntry> entries = new List<Quotes4AllEntry>();
        private int entriesCount = 0;
    }
}
